package com.yanqu.road.logic.pb;

import com.yanqu.road.entity.enums.eChannelType;
import com.yanqu.road.entity.rank.xrank.XChannelRank;
import com.yanqu.road.entity.rank.xrank.XChannelRankPart;
import com.yanqu.road.entity.rank.xrank.XSeasonUserRank;
import com.yanqu.road.entity.rank.xrank.XUserRank;
import com.yanqu.road.logic.helper.CrossChannelHelper;
import com.yanqu.road.logic.xlogic.user.XUserBaseInfoLogic;
import com.yanqu.road.pb.cross3.activity.XRankProto;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class XRankPb {

    public static XRankProto.XUserRankMsg.Builder parseXUserRankMsg(XUserRank userRank, boolean useUpdateMsg) {
        XRankProto.XUserRankMsg.Builder builder = XRankProto.XUserRankMsg.newBuilder();
        builder.setUserId(userRank.getUserId());
        builder.setChannelId(userRank.getChannelId());
        builder.setBaseInfo(useUpdateMsg ?
                XUserBaseInfoLogic.getUpdateInfoBuilder(userRank.getActivityId(), userRank.getConditionType(), userRank.getUserId(), userRank.getBaseInfo())
                : PlayerBasePb.parsePlayerBaseTempMsg(userRank.getBaseInfo()));
        builder.setValue(userRank.getValue().toString());
        if (!StringUtils.isNullOrEmpty(userRank.getParam())) {
            builder.setParam(userRank.getParam());
        }
        builder.setUpdateTime(userRank.getLastUpdateTime());
        return builder;
    }

    public static XRankProto.XUserRankMsg.Builder parseXUserRankMsg(XSeasonUserRank userRank, boolean useUpdateMsg) {
        XRankProto.XUserRankMsg.Builder builder = XRankProto.XUserRankMsg.newBuilder();
        builder.setUserId(userRank.getUserId());
        builder.setChannelId(userRank.getChannelId());

        // 暂时全量
        // builder.setBaseInfo(useUpdateMsg ?
        //        XUserBaseInfoLogic.getUpdateInfoBuilder(userRank.getActivityId(), userRank.getConditionType(), userRank.getUserId(), userRank.getBaseInfo())
        //        : PlayerBasePb.parsePlayerBaseTempMsg(userRank.getBaseInfo()));
        builder.setBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userRank.getBaseInfo()));

        builder.setValue(userRank.getValue().toString());
        if (!StringUtils.isNullOrEmpty(userRank.getParam())) {
            builder.setParam(userRank.getParam());
        }
        builder.setUpdateTime(userRank.getLastUpdateTime());
        return builder;
    }

    public static XUserRank parseXUserRank(int activityId, int conditionType, XRankProto.XUserRankMsg msg) {
        XUserRank userRank = new XUserRank();
        userRank.setActivityId(activityId);
        userRank.setConditionType(conditionType);
        userRank.setChannelId(msg.getChannelId());
        userRank.setServerId(msg.getBaseInfo().getServerId());
        userRank.setUserId(msg.getUserId());
        userRank.setBaseInfo(PlayerBasePb.parseBaseUserInfo(msg.getBaseInfo()));
        userRank.setParam(msg.getParam());
        userRank.setValue(new BigInteger(msg.getValue()));
        userRank.setLastUpdateTime(msg.getUpdateTime());
        return userRank;
    }

    public static XSeasonUserRank parseXSeasonUserRank(int systemId, int seasonId, int conditionType, String rangeKey, XRankProto.XUserRankMsg msg) {
        XSeasonUserRank userRank = new XSeasonUserRank();
        userRank.setSystemId(systemId);
        userRank.setSeasonId(seasonId);
        userRank.setConditionType(conditionType);
        userRank.setRangeKey(rangeKey);
        userRank.setChannelId(msg.getChannelId());
        userRank.setServerId(msg.getBaseInfo().getServerId());
        userRank.setUserId(msg.getUserId());
        userRank.setBaseInfo(PlayerBasePb.parseBaseUserInfo(msg.getBaseInfo()));
        userRank.setParam(msg.getParam());
        userRank.setValue(new BigInteger(msg.getValue()));
        userRank.setLastUpdateTime(msg.getUpdateTime());
        return userRank;
    }

    public static XRankProto.XUserRankListMsg.Builder parseXUserRankListMsg(int activityId, int conditionType, List<XUserRank> userRankList, boolean useUpdateMsg) {
        XRankProto.XUserRankListMsg.Builder builder = XRankProto.XUserRankListMsg.newBuilder();
        builder.setActivityId(activityId);
        builder.setConditionType(conditionType);
        for (XUserRank userRank : userRankList) {
            builder.addRankList(parseXUserRankMsg(userRank, useUpdateMsg));
        }
        return builder;
    }

    public static XRankProto.XSeasonUserRankListMsg.Builder parseXSeasonUserRankListMsg(int systemId, int seasonId, int type, String rangeKey,
                                                                                        List<XSeasonUserRank> userRankList, boolean useUpdateMsg) {
        XRankProto.XSeasonUserRankListMsg.Builder builder = XRankProto.XSeasonUserRankListMsg.newBuilder();
        builder.setSystemId(systemId);
        builder.setSeasonId(seasonId);
        builder.setType(type);
        builder.setRangeKey(rangeKey);
        for (XSeasonUserRank userRank : userRankList) {
            builder.addRankList(parseXUserRankMsg(userRank, useUpdateMsg));
        }
        return builder;
    }

    public static XRankProto.XChannelRankMsg.Builder parseXChannelRankMsg(XChannelRank channelRank) {
        XRankProto.XChannelRankMsg.Builder builder = XRankProto.XChannelRankMsg.newBuilder();
        builder.setChannelId(channelRank.getChannelId());
        builder.setValue(channelRank.getValue().toString());
        if (!StringUtils.isNullOrEmpty(channelRank.getParam())) {
            builder.setParam(channelRank.getParam());
        }
        return builder;
    }

    public static XChannelRank parseXChannelRank(int activityId, int conditionType, XRankProto.XChannelRankMsg msg, long lastUpdateTime) {
        XChannelRank channelRank = new XChannelRank();
        channelRank.setActivityId(activityId);
        channelRank.setConditionType(conditionType);
        channelRank.setChannelId(msg.getChannelId());
        channelRank.setValue(new BigInteger(msg.getValue()));
        channelRank.setLastUpdateTime(lastUpdateTime);
        if (msg.hasParam()) {
            channelRank.setParam(msg.getParam());
        }
        return channelRank;
    }

    public static XRankProto.XChannelRankListMsg.Builder parseXChannelRankListMsg(int activityId, int conditionType, List<XChannelRank> channelRankList) {
        XRankProto.XChannelRankListMsg.Builder builder = XRankProto.XChannelRankListMsg.newBuilder();
        builder.setActivityId(activityId);
        builder.setConditionType(conditionType);
        for (XChannelRank channelRank : channelRankList) {
            builder.addRankList(parseXChannelRankMsg(channelRank));
        }
        return builder;
    }

    public static XRankProto.XChannelRankPartListMsg.Builder parseXChannelRankPartListMsg(int activityId, int conditionType, List<XChannelRankPart> partList) {
        XRankProto.XChannelRankPartListMsg.Builder builder = XRankProto.XChannelRankPartListMsg.newBuilder();
        builder.setActivityId(activityId);
        builder.setConditionType(conditionType);
        for (XChannelRankPart part : partList) {
            builder.addPartMsg(parseXChannelRankPartMsg(part));
        }
        return builder;
    }

    public static XRankProto.XChannelRankPartMsg.Builder parseXChannelRankPartMsg(XChannelRankPart part) {
        XRankProto.XChannelRankPartMsg.Builder builder = XRankProto.XChannelRankPartMsg.newBuilder();
        builder.setChannelId(part.getChannelId());
        builder.setUserId(part.getUserId());
        builder.setValue(part.getValue().toString());
        builder.setNickname(part.getNickname());
        builder.setUpdateTime(part.getUpdateTime());
        return builder;
    }

    public static XChannelRankPart parseXChannelRankPart(int activityId, int conditionType, XRankProto.XChannelRankPartMsg msg) {
        XChannelRankPart rankPart = new XChannelRankPart();
        rankPart.setActivityId(activityId);
        rankPart.setConditionType(conditionType);
        rankPart.setChannelId(msg.getChannelId());
        rankPart.setUserId(msg.getUserId());
        rankPart.setValue(new BigInteger(msg.getValue()));
        rankPart.setNickname(msg.getNickname());
        rankPart.setUpdateTime(msg.getUpdateTime());
        return rankPart;
    }

    /**
     * 给客户端前帮他们转一下渠道号
     */
    public static void fillFlagId(XRankProto.XChannelRankListMsg.Builder builder) {
        int count = builder.getRankListCount();
        for (int i = 0; i < count; i++) {
            XRankProto.XChannelRankMsg rankMsg = builder.getRankList(i);
            eChannelType channelType = eChannelType.forValue(rankMsg.getChannelId());
            if (channelType != null) {
                XRankProto.XChannelRankMsg.Builder tmp = rankMsg.toBuilder().setFlagId(channelType.getPlaceType().getValue());
                builder.setRankList(i, tmp);
            }
        }
    }

    /**
     * 给客户端前帮他们转一下渠道号
     */
    public static void fillFlagId(XRankProto.XUserRankListMsg.Builder builder) {
        int count = builder.getRankListCount();
        for (int i = 0; i < count; i++) {
            XRankProto.XUserRankMsg rankMsg = builder.getRankList(i);
            eChannelType channelType = eChannelType.forValue(rankMsg.getChannelId());
            if (channelType != null) {
                XRankProto.XUserRankMsg.Builder tmp = rankMsg.toBuilder().setFlagId(channelType.getPlaceType().getValue());
                builder.setRankList(i, tmp);
            }
        }
    }

    /**
     * 给客户端前帮他们转一下渠道号
     */
    public static void fillFlagId(XRankProto.XSeasonUserRankListMsg.Builder builder) {
        int count = builder.getRankListCount();
        for (int i = 0; i < count; i++) {
            XRankProto.XUserRankMsg rankMsg = builder.getRankList(i);
            eChannelType channelType = eChannelType.forValue(rankMsg.getChannelId());
            if (channelType != null) {
                XRankProto.XUserRankMsg.Builder tmp = rankMsg.toBuilder().setFlagId(channelType.getPlaceType().getValue());
                builder.setRankList(i, tmp);
            }
        }
    }

    /**
     * 分割成小包（会清空原有list）
     */
    public static List<XRankProto.XUserRankListMsg.Builder> cutXUserRankList(XRankProto.XUserRankListMsg.Builder builder) {

        // 判断数量是否需要分割
        int size = CrossChannelHelper.getSyncRankListSize();
        if (builder.getRankListCount() <= size) {
            return Collections.singletonList(builder);
        }

        // 拿旧的list
        List<XRankProto.XUserRankMsg> list = builder.getRankListList();
        // 清空旧的list，方便clone
        builder.clearRankList();
        // list分割
        List<List<XRankProto.XUserRankMsg>> cutList = new ArrayList<>();
        cutList.add(new ArrayList<>(size));
        List<XRankProto.XUserRankMsg> lastList = cutList.get(cutList.size() - 1);
        for (XRankProto.XUserRankMsg rankMsg : list) {
            if (lastList.size() >= size) {
                cutList.add(new ArrayList<>(size));
                lastList = cutList.get(cutList.size() - 1);
            }
            lastList.add(rankMsg);
        }
        // 剩下的放新的builder
        List<XRankProto.XUserRankListMsg.Builder> resultList = new ArrayList<>();
        for (List<XRankProto.XUserRankMsg> msgList : cutList) {
            XRankProto.XUserRankListMsg.Builder toAddBuilder = builder.clone();
            toAddBuilder.addAllRankList(msgList);
            resultList.add(toAddBuilder);
        }
        return resultList;
    }

    /**
     * 分割成小包（会清空原有list）
     */
    public static List<XRankProto.XChannelRankPartListMsg.Builder> cutXChannelPartList(XRankProto.XChannelRankPartListMsg.Builder builder) {

        // 判断数量是否需要分割
        int size = CrossChannelHelper.getSyncRankListSize();
        if (builder.getPartMsgCount() <= size) {
            return Collections.singletonList(builder);
        }

        // 拿旧的list
        List<XRankProto.XChannelRankPartMsg> list = builder.getPartMsgList();
        // 清空旧的list，方便clone
        builder.clearPartMsg();
        // list分割
        List<List<XRankProto.XChannelRankPartMsg>> cutList = new ArrayList<>();
        cutList.add(new ArrayList<>(size));
        List<XRankProto.XChannelRankPartMsg> lastList = cutList.get(cutList.size() - 1);
        for (XRankProto.XChannelRankPartMsg rankMsg : list) {
            if (lastList.size() >= size) {
                cutList.add(new ArrayList<>(size));
                lastList = cutList.get(cutList.size() - 1);
            }
            lastList.add(rankMsg);
        }
        // 放新的builder
        List<XRankProto.XChannelRankPartListMsg.Builder> resultList = new ArrayList<>();
        for (List<XRankProto.XChannelRankPartMsg> msgList : cutList) {
            XRankProto.XChannelRankPartListMsg.Builder toAddBuilder = builder.clone();
            toAddBuilder.addAllPartMsg(msgList);
            resultList.add(toAddBuilder);
        }
        return resultList;
    }
}
